﻿using System;
using System.Collections.Specialized;
using System.Web.Security;
using NUnit.Framework;
using ScrappyDB.Membership;
using NUnit.Framework;

namespace ScrappyDB.IntegrationTests.Membership
{  
    /// <summary>
    ///This is a test class for ScrappyDBRoleProviderTest and is intended
    ///to contain all ScrappyDBRoleProviderTest Unit Tests
    ///</summary>
    [TestFixture]
    public class SdbRoleProviderTest
    {
        string rolename = "TestRole";
        string rolename2 = "TestRole2";

        string username = "test";
        string username2 = "test2";
        string password = "password";
        string email = "ScrappyDB.IntegrationTests@scrappydog.com";
        string passwordQuestion = "Test Question";
        string passwordAnswer = "Test Answer";
        bool isApproved = false;
        object providerUserKey = new Guid("00000000-0000-0000-0000-000000000001");
        object providerUserKey2 = new Guid("00000000-0000-0000-0000-000000000002");
        private SdbRoleProvider _roleProvider;
        private SdbMembershipProvider _membershipProvider;


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes

        [SetUp]
        public void MyTestInitialize()
        {
            Cleanup();
        }
        
        //Use TestCleanup to run code after each test has run
        [TearDown]
        public void MyTestCleanup()
        {
            Cleanup();
        }
        
        public void Cleanup()
        {
            InitializeRoleProvider();
            InitializeMembershipProvider();

            _roleProvider.DeleteRole(rolename, false);
            _roleProvider.DeleteRole(rolename2, false);

            _membershipProvider.DeleteUser(username, false);
            _membershipProvider.DeleteUser(username2, false);

        }

        #endregion


        /// <summary>
        ///A test for RoleExists
        ///</summary>
        [Test]
        public void RoleExistsTest()
        {
            _roleProvider.CreateRole(rolename);
            var actual = _roleProvider.RoleExists(rolename);

            Assert.AreEqual(true, actual);
        }

        /// <summary>
        ///A test for RemoveUsersFromRoles
        ///</summary>
        [Test]
        public void RemoveUsersFromRolesTest()
        {
            MembershipCreateStatus statusActual;
            MembershipUser actual = _membershipProvider.CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out statusActual);

            _roleProvider.CreateRole(rolename);

            var usernames = new string[] { username };
            var rolenames = new string[] { rolename };

            _roleProvider.AddUsersToRoles(usernames, rolenames);

            var roles = _roleProvider.GetRolesForUser(username);

            Assert.AreEqual(1, roles.Length);
            Assert.AreEqual(rolename, roles[0]);

            _roleProvider.RemoveUsersFromRoles(usernames, rolenames);

            roles = _roleProvider.GetRolesForUser(username);

            Assert.AreEqual(0, roles.Length);

        }

        /// <summary>
        ///A test for IsUserInRole
        ///</summary>
        [Test]
        public void IsUserInRoleTest()
        {
            MembershipCreateStatus statusActual;
            MembershipUser user = _membershipProvider.CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out statusActual);

            _roleProvider.CreateRole(rolename);
            _roleProvider.CreateRole(rolename2);

            var usernames = new string[] { username };
            var rolenames = new string[] { rolename };

            _roleProvider.AddUsersToRoles(usernames, rolenames);

            var actual = _roleProvider.IsUserInRole(username, rolename);
            Assert.AreEqual(true, actual);

            var actual2 = _roleProvider.IsUserInRole(username, rolename2);
            Assert.AreEqual(false, actual2);
        }

        /// <summary>
        ///A test for GetUsersInRole
        ///</summary>
        [Test]
        public void GetUsersInRoleTest()
        {
            MembershipCreateStatus statusActual;
            MembershipUser user = _membershipProvider.CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out statusActual);
            MembershipUser user2 = _membershipProvider.CreateUser(username2, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey2, out statusActual);

            _roleProvider.CreateRole(rolename);

            var usernames = new string[] { username , username2};
            var rolenames = new string[] { rolename };

            _roleProvider.AddUsersToRoles(usernames, rolenames);

            var actual = _roleProvider.GetUsersInRole(rolename);

            Assert.AreEqual(2, actual.Length);
        }

        /// <summary>
        ///A test for GetRolesForUser
        ///</summary>
        [Test,Ignore]
        public void GetRolesForUserTest()
        {
            SdbRoleProvider target = new SdbRoleProvider(); 
            string username = string.Empty; 
            string[] expected = null; 
            string[] actual;
            actual = target.GetRolesForUser(username);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for GetAllRoles
        ///</summary>
        [Test]
        public void GetAllRolesTest()
        {
            _roleProvider.CreateRole(rolename);
            _roleProvider.CreateRole(rolename2);

            var roles = _roleProvider.GetAllRoles();

            Assert.IsTrue(roles.Length == 2);
        }

        /// <summary>
        ///A test for FindUsersInRole
        ///</summary>
        [Test,Ignore]
        public void FindUsersInRoleTest()
        {
            SdbRoleProvider target = new SdbRoleProvider(); 
            string rolename = string.Empty; 
            string usernameToMatch = string.Empty; 
            string[] expected = null; 
            string[] actual;
            actual = target.FindUsersInRole(rolename, usernameToMatch);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for DeleteRole
        ///</summary>
        [Test]
        public void DeleteRoleTest()
        {
            _roleProvider.CreateRole(rolename);
            var roles = _roleProvider.GetAllRoles();

            Assert.IsTrue(roles.Length == 1);

            var actual = _roleProvider.DeleteRole(rolename, false);

            Assert.AreEqual(true, actual);
        }

        /// <summary>
        ///A test for CreateRole
        ///</summary>
        [Test]
        public void CreateRoleTest()
        {

            _roleProvider.CreateRole(rolename);

            var roles =_roleProvider.GetAllRoles();

            Assert.IsTrue(roles.Length == 1);
            Assert.AreEqual(rolename, roles[0]);
        }



        /// <summary>
        ///A test for AddUsersToRoles
        ///</summary>
        [Test]
        public void AddUsersToRolesTest()
        {
            MembershipCreateStatus statusActual;
            MembershipUser actual = _membershipProvider.CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out statusActual);

            _roleProvider.CreateRole(rolename);

            var usernames = new string[]{username};
            var rolenames = new string[]{rolename};

            _roleProvider.AddUsersToRoles(usernames, rolenames);

            var roles = _roleProvider.GetRolesForUser(username);

            Assert.AreEqual(1, roles.Length);
            Assert.AreEqual(rolename, roles[0]);
        }

        private void InitializeRoleProvider()
        {
            _roleProvider = new SdbRoleProvider();
            var config =new NameValueCollection()
                            {
                                {"ApplicationName" , "ScrappyDB.IntegrationTests"}
                            };
            _roleProvider.Initialize("SdbRoleProvider",config);
            
        }        
        
        private void InitializeMembershipProvider()
        {
            _membershipProvider = new SdbMembershipProvider();
            var config = new NameValueCollection
                             {
                                 {"applicationName", "ScrappyDB.IntegrationTests"},
                                 {"enablePasswordRetrieval", "false"},
                                 {"enablePasswordReset", "true"},
                                 {"requiresQuestionAndAnswer", "true"},
                                 {"requiresUniqueEmail", "false"},
                                 {"passwordFormat", "Clear"},
                                 {"maxInvalidPasswordAttempts", "5"},
                                 {"minRequiredPasswordLength", "7"},
                                 {"minRequiredNonalphanumericCharacters", "1"},
                                 {"passwordAttemptWindow", "10"}
                             };

            _membershipProvider.Initialize(config["name"], config);
        }

    }
}
